package com.hly.tool.list;

import com.matrixone.apps.domain.DomainConstants;
import com.matrixone.apps.domain.util.MapList;
import matrix.util.MatrixException;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * Copyright@ Apache Open Source Organization
 *
 * @Auther: HLY
 * @Date: 2023-11-06-17:05
 * @Description:
 */
public class MapListUtil {
    private static final Logger _logger = Logger.getLogger("JDX_MapListUtil_mxJPO");


    /**
     * @param dataList
     * @param key
     * @return MapList
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description:数据去重
     */
    public MapList dictinct(MapList dataList, String key) {
        List<Map> list = (List<Map>) dataList.stream().filter(distinctByKey(o -> ((Map) o).get(key))).collect(Collectors.toList());
        MapList result = new MapList(list.size());
        result.addAll(list);
        return result;
    }

    /**
     * @param keyExtractor
     * @return Predicate<T>
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description: 数据去重
     */
    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


    /**
     * @param mapList 数据集合
     * @param pKey    父节点与子节点的关系 key
     * @param cKey    子节点与父节点的关系 key
     * @param rootMap 根节点map
     * @return Map
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description: 把MapList 转成 Tree 结构
     */
    public static Map toTree(MapList mapList, String pKey, String cKey, Map rootMap) throws Exception {
        try {
            if (ifHasChild(mapList, (String) rootMap.get(cKey), pKey)) {
                // 最主要的一步，递归，找到孩子节点，然后塞到Map中
                rootMap.put("children", getChildren(rootMap, mapList, pKey, cKey));
            } else {
                rootMap.put("children", new MapList());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rootMap;
    }


    /**
     * @param mapList 数据集合
     * @param cVal    子节点与父节点的值
     * @param pKey    父节点与子节点的关系 key
     * @return boolean
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description: 判断一个Map是否有子节点, 加快程序运行
     */
    private static boolean ifHasChild(MapList mapList, String cVal, String pKey) {
        int result = 0;

        for (int i = 0; i < mapList.size(); i++) {
            Map map_i = (Map) mapList.get(i);
            if (map_i.get(pKey) != null && map_i.get(pKey).equals(cVal)) {
                result++;
            }
        }
        return result > 0 ? true : false;
    }


    /**
     * @param rootMap 根节点map
     * @param mapList 数据集合
     * @param pKey    父节点与子节点的关系 key
     * @param cKey    子节点与父节点的关系 key
     * @return MapList
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description:获取到子节点数据
     */
    private static MapList getChildren(Map rootMap, MapList mapList, String pKey, String cKey) throws MatrixException {
//        JSONArray childrenArray = new JSONArray();
        MapList childrenList = new MapList();
        // 递归返回条件，如果没返回条件就死循环了
        if (mapList == null || mapList.isEmpty()) {
            //没有子节点情况下
            return childrenList;
        }
        for (int i = 0; i < mapList.size(); i++) {
            Map map_i = (Map) mapList.get(i);
            if (((String) map_i.get(pKey)).equals((String) rootMap.get(cKey))) {
//                JSONObject tmpJson = new JSONObject(map_i);
                //  递归代码
                if (ifHasChild(mapList, (String) map_i.get(cKey), pKey)) {
                    map_i.put("children", getChildren(map_i, mapList, pKey, cKey));
                } else {
                    map_i.put("children", new MapList());
                }

                childrenList.add(map_i);
            }
        }
        return childrenList;
    }


    /**
     * @param dataList
     * @param map
     * @param result
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description:添加所有的子节点数据 所有的子节点数据都添加到result中
     */
    public static void addChild(MapList dataList, Map map, MapList result) {
        //子节点集合
        List<Map> childList = (List<Map>) dataList.stream().filter(m -> ((Map) m).get(DomainConstants.SELECT_FROM_ID).equals(map.get(DomainConstants.SELECT_ID))).collect(Collectors.toList());
        if (childList != null && !childList.isEmpty()) {
            result.addAll(childList);

            for (int i = 0; i < childList.size(); i++) {
                Map map_i = childList.get(i);
                addChild(dataList, map_i, result);
            }
        }
    }

    /**
     * @param dataList
     * @param map
     * @param result
     * @return void
     * @Author HLY
     * @CreateTime 2023/11/6
     * @Description:添加所有的父节点数据 所有的父节点数据都添加到result中
     */
    public static void addParent(MapList dataList, Map map, MapList result) {
        //父节点集合
        List<Map> parentList = (List<Map>) dataList.stream().filter(m -> ((Map) m).get(DomainConstants.SELECT_ID).equals(map.get(DomainConstants.SELECT_FROM_ID))).collect(Collectors.toList());
        if (parentList != null && !parentList.isEmpty()) {
            result.addAll(parentList);

            for (int i = 0; i < parentList.size(); i++) {
                Map map_i = parentList.get(i);
                addParent(dataList, map_i, result);
            }
        }
    }

}
